﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EuroManager.Domain.Simulator.Engine;
using EuroManager.Domain.Simulator.Helpers;
using NUnit.Framework;

namespace EuroManager.Domain.Simulator.Tests.Helpers
{
    [TestFixture]
    public class PhysicsTests
    {
        [Test]
        public void ShouldCalculateLocationWhenMovingWithConstantSpeed()
        {
            Vector2D newLocation = Physics.Location(new Vector2D(10, 10), new Vector2D(-3, -2), 2);

            Assert.AreEqual(new Vector2D(4, 6), newLocation);
        }

        [Test]
        public void ShouldCalculateLocationWhenAccelerating()
        {
            Vector2D newLocation = Physics.Location(new Vector2D(10, 5), Vector2D.UnitX, 1, 2);

            Assert.AreEqual(new Vector2D(14, 5), newLocation);
        }

        [Test]
        public void ShouldCalculateTimeToCoverDistanceWithConstantSpeed()
        {
            float time = Physics.Time(2, 6);

            Assert.AreEqual(3, time);
        }

        [Test]
        public void ShouldCalculateTimeToReachFinalSpeed()
        {
            float time = Physics.Time(3, 1, -1);

            Assert.AreEqual(2, time);
        }

        [Test]
        public void ShouldCalculateVelocityAfterAccelerating()
        {
            Vector2D velocity = Physics.Velocity(new Vector2D(0, 3), Vector2D.UnitX, 4);

            Assert.AreEqual(new Vector2D(4, 3), velocity);
        }

        [Test]
        public void ShouldCalculateVelocityAfterAcceleratingToMaxSpeed()
        {
            Vector2D velocity = Physics.Velocity(new Vector2D(0, 3), Vector2D.UnitX, 1e8f, 5);

            Assert.AreEqual(5, velocity.Length, Maths.Epsilon);
            Assert.IsTrue(Vector2D.Equals(new Vector2D(5, 0), velocity, Maths.Epsilon));
        }

        [Test]
        public void ShouldCalculateVelocityAfterDecelerating()
        {
            Vector2D velocity = Physics.Velocity(new Vector2D(2, 0), 1, 1);

            Assert.AreEqual(new Vector2D(1, 0), velocity);
        }

        [Test]
        public void ShouldCalculateStartSpeedForConstantMovement()
        {
            float speed = 15;
            float result = Physics.StartSpeed(speed, 50, 0);

            Assert.AreEqual(speed, result);
        }

        [Test]
        public void ShouldCalculateStartSpeedForDeceleratedMovement()
        {
            float result = Physics.StartSpeed(2, 3, 2);

            Assert.AreEqual(4, result);
        }

        [Test]
        public void ShouldCalculateDistanceCoveredWhenDecelerating()
        {
            Assert.AreEqual(6.25f, Physics.Distance(5, 2), Maths.Epsilon);
        }

        [Test]
        public void ShouldCalculateDistanceCoveredAfterAccelerating()
        {
            Assert.AreEqual(9, Physics.Distance(0, 2, 3));
        }
    }
}
